package com.xstv.mall.backend.configurer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import java.time.Duration;

/**
 * @ClassName CacheConfig
 * @Description 配置redis为spring boot cache
 * @Author zou
 * @Date 2019/6/4 10:16
 * 
 *      spring cache 使用redis作为缓存的依赖
 *      添加此依赖后，打开@EnableCaching注解，声明式缓存(@Cacheable等)就可以用了
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        使用@EnableConfigurationProperties注解时需要引入下列依赖
        配合如@ConfigurationProperties(prefix = "spring.cache")使用，可以将配置文件中的值直接注入到实体内
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
 **/
@Configuration
@EnableCaching
@EnableConfigurationProperties({CacheProperties.class})
public class CacheConfig extends CachingConfigurerSupport {

   /**
    * 缓存采用jackson序列化为json格式
    * @author zouzheng
    * @date 10:22 2019/6/4
    * @param prop 参数通过@EnableConfigurationProperties({CacheProperties.class})注入
    * @return
    **/
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties prop) {
        //jackson序列机
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

        //缓存失效时间
        Duration timeToLive = prop.getRedis().getTimeToLive();

        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(timeToLive)
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
    }

}
